package com.iamteer.day14;
/**
主要回顾：线程停止、守护线程
	
停止线程：
	1. 通过变量去控制
	2. 如果线程处于等待状态，则需要把线程唤醒（通过 notify 或者 interrupt 方法）

守护线程：（后台线程）一个进程如果只剩下守护线程，那么守护线程也会死亡
	线程默认都不是守护线程，可以通知 setDaemon(true);来设置
	
join 方法：
	一个线程如果执行 join 语句，那么就有新的线程加入，执行该语句的线程必须要让步给新加入的线程，
	等新加入线程完成任务后，原线程才能才能继续运行。
	
 */

//停止线程演示类
class StopThread extends Thread {
	boolean flag = true;
	
	public StopThread(String name) {
		super(name);
	}
	@Override
	public synchronized void run() {
		int i = 0;
		while (flag) {

			System.out.println(Thread.currentThread().getName() + ": " + i);
			i++;
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}	
}

//守护线程演示类
class DaemonThread extends Thread{
	
	public DaemonThread(String name) {
		super(name);
	}
	
	@Override
	public void run() {
		for(int i = 1; i <= 100; i++){
			System.out.println("更新包目前下载 " + i + " %");
			if (i == 100) {
				System.out.println("更新包下载完成，准备安装...");
			}
			try {
				sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

//以下两个类用于演示 join 语句
class Mum extends Thread{
	@Override
	public void run() {
		System.out.println("妈妈洗菜。。。");
		System.out.println("妈妈切菜。。。");
		System.out.println("妈妈炒菜，发现没酱油了。。。");
		
		//让儿子去打酱油
		Son son = new Son();
		son.start();
		
		try {
			son.join();	//如果没有 join 方法，可以看到一个有趣的现象：儿子一走，大家不开始吃饭了。。。
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println("妈妈继续炒菜");
		System.out.println("菜好了，全家吃饭");
	}
}

class Son extends Thread{
	@Override
	public void run() {
		System.out.println("儿子下楼。。。");
		System.out.println("儿子飞奔。。。");
		System.out.println("儿子到商店。。。");
		System.out.println("儿子买到酱油。。。");
		System.out.println("儿子到家。。。");
	}
}

public class OtherThreadMethods extends Thread {
	boolean flag = true;
	
	public static void main(String[] args) {
		
		//停止线程演示
		StopThread o = new StopThread("Thread");
		o.start();
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getName() + ": " + i);
			if (i >= 80) {
				o.flag = false;	//改变线程的循环控制变量
				//唤醒线程（以防线程一直在睡着），有两种方法：
//				o.interrupt();		//1：把线程的等待状态强制清除，被清除状态的线程会接收到一个 InterruptedException
				synchronized (o) {	//2：唤醒线程
					o.notify();
				}
			}
		}
		
		
		//守护线程演示
		DaemonThread d = new DaemonThread("Daemon");
		d.setDaemon(true);
		System.out.println(d.isDaemon());
		d.start();
		
		
		//join 方法演示
		Mum mum = new Mum();
		mum.start();
		
	}
}
